-- 房间管理模块
-- Author: Colocasia
-- Date: 2018-08-07

local skynet = require 'skynet';
local class = require 'class';
local handler = require 'handler';
local table = require 'us.table';

-- 常量
local ENUM_ROOM = require 'room_const';

---以创建代理数量
local room_count = 0
---所有的房间列表
-- ex:
-- room_list = {
--     [room_id1] = room_1,
--     [room_id2] = room_2,
--     [room_id3] = room_3,
--     ...
-- }
local room_list = {}


---客户端展示的cuid转为服务器id
-- ex:
-- room_cuid = {
--     [room_cuid1] = room_1,
--     [room_cuid2] = room_2,
--     [room_cuid3] = room_3,
--     ...
-- }
local room_cuid = {}


---空闲的游戏房间(数组)
-- ex: 
-- room_idle = {
--     room_1, 
--     room_2, 
--     room_3, 
--     ...
-- }
local room_idle = {}


---等待玩家进入的房间(散列)
-- ex:
-- room_wait = { 
--     [room_cuid1] = room_1, 
--     [room_cuid2] = room_2,
--     [room_cuid3] = room_3,
--     ...
-- }
local room_wait = {}


---正在游戏的房间列表(散列)
-- ex:
-- room_game = { 
--     [guid_1] = room_1, 
--     [guid_2] = room_2,
--     [guid_3] = room_3,
--     ...
-- }
local room_game = {}


---需要展示在大厅的房间GUID集合
-- ex: 
-- hall_guid = {
--     room_cuid1,
--     room_cuid2,
--     room_cuid3,
--     ...
-- }
local hall_guid = {}


---常用函数
---@type fun @获得当前物理机时间
local skynet_time = skynet.time;
---@type fun @移除表内容
local table_insert = table.insert;
---@type fun @移除表内容
local table_remove = table.remove;
---@type fun @遍历表内容
local table_foreach = table.foreach;
---@type fun @合并表内容
local table_merge = table.merge;


local M = class('room_mgr', handler);


function M:ctor()
end


---生成客户端ID
local function _gen_cuid()
    local room_cuid = 0
    return function()
        room_cuid = room_cuid + 1
        return room_cuid;
    end
end
local gen_cuid = _gen_cuid();


---是否可以创建房间
local function can_create()
    return room_count < ENUM_ROOM.MAX_COUNT;
end


---创建房间代理
local function create_room_agent()
    if not can_create() then return end
    room_count = room_count + 1;
    local room = skynet.newservice("us_room_agent", skynet.self(), room_count);
    room_list[room_count] = room;
    return room;
end


---获取一个空闲房间代理
local function get_idle_room()
    if #room_idle < 1 then
        return create_room_agent();
    else
        return table_remove(room_idle);
    end
end


---通过id获得房间地址
function M:get_room_by_id(room_id)
    return room_list[room_id];
end


---通过GUID获得房间地址
function M:get_room_by_guid(guid)
    return room_game[guid];
end


---通过CUID获得房间地址
function M:get_room_by_guid(cuid)
    return room_cuid[cuid];
end


---申请房间
function M:apply_room(params)
    local room = get_idle_room();
    if not room then return end

    local cuid = gen_cuid();
    room_cuid[cuid] = room;
    room_wait[cuid] = room;

    local params = params or {};
    params.cuid = cuid;
    self:send_room_cmd(room, "launch", params);

    local info = {
        server = '',
        addr = room,
        cuid = cuid,
    }
    return info;
end





return M;
